//
//  SocketManager.m
//  CocoaSyncSocket
//
//  Created by 崔逢举 on 20/03/28.
//  Copyright © 2020年 崔逢举 . All rights reserved.
//

#import "SocketManager.h"
#import "GCDAsyncSocket.h" // for TCP


static const uint16_t Kport = 8888;


@interface SocketManager()<GCDAsyncSocketDelegate>
{
    GCDAsyncSocket *gcdSocket;
    
    NSDictionary *currentPacketHead;
    
}

@property (nonatomic,strong)NSMutableArray *sockets;

@end

@implementation SocketManager

+ (instancetype)shareInstance {
    static dispatch_once_t onceToken;
    static SocketManager *instance = nil;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc]init];
        [instance initSocket];
    });
    return instance;
}

- (void)initSocket {
    gcdSocket = [[GCDAsyncSocket alloc] initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    
    self.sockets = [NSMutableArray array];
}


#pragma mark - 对外的一些接口

//等待连接
- (BOOL)accept {
    NSError *error = nil;
    
    BOOL isSuccess =   [gcdSocket acceptOnPort:Kport error:&error];
    if (isSuccess) {
        NSLog(@"监听成功，等待连接");
        return YES;
    } else{
        NSLog(@"监听失败，原因：%@",error);
        return NO;
    }
}

//发送消息
- (void)sendMsg {
    
    NSData *data  = [@"iOS大佬们" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data1  = [@"大家好" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data2  = [@"我是崔逢举" dataUsingEncoding:NSUTF8StringEncoding];
    
    
    NSData *data3  = [@"今天第一次参与分享" dataUsingEncoding:NSUTF8StringEncoding];
    NSData *data4  = [@"分享的不好还请大家多多包涵" dataUsingEncoding:NSUTF8StringEncoding];
    
    [self sendData:data :@"txt"];
    [self sendData:data1 :@"txt"];
    [self sendData:data2 :@"txt"];
    [self sendData:data3 :@"txt"];
    [self sendData:data4 :@"txt"];
    
    NSString *filePath = [[NSBundle mainBundle]pathForResource:@"timg" ofType:@"png"];
    
    NSData *data5 = [NSData dataWithContentsOfFile:filePath];
    
    [self sendData:data5 :@"img"];
}

- (void)sendData:(NSData *)data :(NSString *)type {
    NSUInteger size = data.length;
    
    NSMutableDictionary *headDic = [NSMutableDictionary dictionary];
    [headDic setObject:type forKey:@"type"];
    [headDic setObject:[NSString stringWithFormat:@"%ld",size] forKey:@"size"];
    NSString *jsonStr = [self dictionaryToJson:headDic];
    
    
    NSData *lengthData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    
    
    NSMutableData *mData = [NSMutableData dataWithData:lengthData];
    //分界
    [mData appendData:[GCDAsyncSocket CRLFData]];
    
    [mData appendData:data];
    
    
    //第二个参数，请求超时时间
    [self.sockets[0] writeData:mData withTimeout:-1 tag:110];
    
}

//写入回调
- (void)socket:(GCDAsyncSocket*)sock didWriteDataWithTag:(long)tag {
    NSLog(@"回调,tag:%ld",tag);
}

//字典转为Json字符串
- (NSString *)dictionaryToJson:(NSDictionary *)dic {
    NSError *error = nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error];
    return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}


#pragma mark - GCDAsyncSocketDelegate

- (void)socket:(GCDAsyncSocket *)sock didAcceptNewSocket:(GCDAsyncSocket *)newSocket {
    NSLog(@"接受到客户端连接");
    
    [self.sockets addObject:newSocket];
    [newSocket readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:110];
    //    [newSocket readDataWithTimeout:-1 tag:110];
    
}

- (void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag {
    //先读取到当前数据包头部信息
    if (!currentPacketHead) {
        currentPacketHead = [NSJSONSerialization
                             JSONObjectWithData:data
                             options:NSJSONReadingMutableContainers
                             error:nil];
        
        
        if (!currentPacketHead) {
            NSLog(@"error：当前数据包的头为空");
            
            //断开这个socket连接或者丢弃这个包的数据进行下一个包的读取
            
            //....
            
            return;
        }
        
        NSUInteger packetLength = [currentPacketHead[@"size"] integerValue];
        
        //读到数据包的大小
        [sock readDataToLength:packetLength withTimeout:-1 tag:110];
        
        return;
    }
    
    
    //正式的包处理
    NSUInteger packetLength = [currentPacketHead[@"size"] integerValue];
    //说明数据有问题
    if (packetLength <= 0 || data.length != packetLength) {
        NSLog(@"error：当前数据包数据大小不正确");
        return;
    }
    
    NSString *type = currentPacketHead[@"type"];
    
    if ([type isEqualToString:@"img"]) {
        NSLog(@"图片设置成功");
        self.recvImg.image = [UIImage imageWithData:data];
    } else{
        
        NSString *msg = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"收到消息:%@",msg);
    }
    
    currentPacketHead = nil;
    
    [sock readDataToData:[GCDAsyncSocket CRLFData] withTimeout:-1 tag:110];
}




@end
